package de.nak.notendb.action;

import java.util.ArrayList;
import java.util.List;

import com.opensymphony.xwork2.ActionSupport;

import de.nak.notendb.model.ExaminationResult;
import de.nak.notendb.model.Maniple;
import de.nak.notendb.model.OralExaminationResult;
import de.nak.notendb.service.exceptions.NoManipleAvailableException;
import de.nak.notendb.service.interfaces.IExaminationResultService;
import de.nak.notendb.service.interfaces.IManipleService;

/**
 * The Action to show the OralExaminationOverview.
 * 
 * @author Christian Baumhof
 * 
 */
public class ShowOralExamOverviewAction extends ActionSupport {

	/**
	 * The generated serialVersionUID.
	 */
	private static final long serialVersionUID = 2045913449749790875L;

	/**
	 * The Service to load Maniples.
	 */
	private IManipleService manipleService;

	/**
	 * The Service to load ExaminatonResults.
	 */
	private IExaminationResultService examinationResultService;

	/**
	 * The id of the selected Maniple.
	 */
	private Long selectedManipleId;

	/**
	 * The list of available Maniples.
	 */
	private List<Maniple> maniples;

	/**
	 * The list of ExaminationResults.
	 */
	private List<ExaminationResult> results;

	/**
	 * Is true, if finished exams shall be shown.
	 */
	private Boolean showFinishedExams;
	private List<Boolean> openOralExam;

	@Override
	public String execute() throws Exception {
		// load maniples
		try {
			maniples = manipleService.listManiples();
		} catch (NoManipleAvailableException exception) {
			return "DATA_NOT_FOUND";
		}
		if (selectedManipleId == null) {
			selectedManipleId = maniples.get(0).getId();
		}

		// initialize showFinishedExams
		if (showFinishedExams == null) {
			showFinishedExams = false;
		}

		// load results
		if (showFinishedExams) {
			results = examinationResultService
					.listExaminationResultsWithOralExam(selectedManipleId);
		} else {
			results = examinationResultService
					.listExaminationResultsWithOpenOralExam(selectedManipleId);
		}

		// initiate openOralExam
		openOralExam = new ArrayList<Boolean>();
		for (ExaminationResult result : results) {
			openOralExam.add(isOpenOralExam(result));
		}

		return SUCCESS;
	}

	/**
	 * Return the id the selected Maniple
	 * 
	 * @return Long id.
	 */
	public Long getSelectedManipleId() {
		return selectedManipleId;
	}

	/**
	 * Setter for the id of the selected Maniple.
	 * 
	 * @param the
	 *            id of the selected Maniple.
	 */
	public void setSelectedManipleId(Long selectedManipleId) {
		this.selectedManipleId = selectedManipleId;
	}

	/**
	 * Returns a list of ExaminationResults.
	 * 
	 * @return a list of ExaminationResults.
	 */
	public List<ExaminationResult> getResults() {
		return results;
	}

	/**
	 * Setter for the list of ExaminationResults.
	 * 
	 * @param List
	 *            <ExaminationResult> results
	 */
	public void setResults(List<ExaminationResult> results) {
		this.results = results;
	}

	/**
	 * Returns true, if finished exam should be shown
	 * 
	 * @return true, if finished exam should be shown
	 */
	public Boolean getShowFinishedExams() {
		return showFinishedExams;
	}

	/**
	 * Setter for the boolean showFinishedExams
	 * 
	 * @param Boolean
	 *            showFinishedExams
	 */
	public void setShowFinishedExams(Boolean showFinishedExams) {
		this.showFinishedExams = showFinishedExams;
	}

	/**
	 * Returns the list of Maniples.
	 * 
	 * @return the list of Maniples.
	 */
	public List<Maniple> getManiples() {
		return maniples;
	}

	/**
	 * Setter for the ManipleService.
	 * 
	 * @param IManipleService
	 *            manipleService.
	 */
	public void setManipleService(IManipleService manipleService) {
		this.manipleService = manipleService;
	}

	/**
	 * Setter for the ExaminationResultService
	 * 
	 * @param IExaminationResultService
	 *            examinationResultService
	 */
	public void setExaminationResultService(
			IExaminationResultService examinationResultService) {
		this.examinationResultService = examinationResultService;
	}

	/**
	 * Returns a list of Boolean showing if the corresponding ExaminationResult
	 * is an open oral exam.
	 * 
	 * @return a list of Boolean showing if the corresponding ExaminationResult
	 *         is an open oral exam.
	 */
	public List<Boolean> getOpenOralExam() {
		return openOralExam;
	}

	/**
	 * Returns true, if the given result is an open oral exam.
	 * 
	 * @param ExaminationResult
	 *            result.
	 * @return true, if the given result is an open oral exam.
	 */
	private Boolean isOpenOralExam(ExaminationResult result) {
		if (result.getOralExaminationResults() == null) {
			return true;
		}
		for (OralExaminationResult oralExam : result
				.getOralExaminationResults()) {
			if (oralExam.isValid()) {
				return false;
			}
		}
		return true;
	}

}
